function topologicalSort(graph) {
    let inDegree = {};
    // 初始化入度
    for (let node of Object.keys(graph)) {
        inDegree[node] = 0;
    }
    for (let node of Object.keys(graph)) {
        for (let neighbor of graph[node]) {
            inDegree[neighbor] = (inDegree[neighbor] || 0) + 1;
        }
    }
    let queue = [];
    for (let node of Object.keys(inDegree)) {
        if (inDegree[node] === 0) {
            queue.push(node);
        }
    }
    let result = [];
    while (queue.length > 0) {
        let node = queue.shift();
        result.push(node);
        if (graph[node]) {
            for (let neighbor of graph[node]) {
                inDegree[neighbor]--;
                if (inDegree[neighbor] === 0) {
                    queue.push(neighbor);
                }
            }
        }
    }
    if (result.length!== Object.keys(graph).length) {
        throw new Error("Graph contains a cycle");
    }
    return result;
}
function test(){
    // 示例图的表示，键是节点，值是它的邻居节点数组
    let graph = {
        'A': ['B', 'C'],
        'B': ['C'],
        'D': ['A'],
        'C': [],
    };
    console.log(topologicalSort(graph));
}

function topoSortObj(nodes,namePro='name',depPro='dependencies'){
    const objGraph = {}
    nodes.forEach(node=>{
        if(node[depPro] && node[depPro].length){
            objGraph[node[namePro]] = node[depPro]
        }
        else{
            objGraph[node[namePro]] = []
        }
    })
    const sortObj = topologicalSort(objGraph)
    return sortObj.reverse();
}

function execObj(nodesConfig,cb){
    const nodes = topoSortObj(nodesConfig)
    const udfObjs = {}
    nodesConfig.forEach(node=>udfObjs[node.name]=node)
    nodes.forEach(node=>{
        cb(node,udfObjs)
    })
}

module.exports = {
    topologicalSort, 
    topoSortObj,
    execObj
}